import { MipmapGenerator } from './mipmapGenerator';
 
export class TrilinearFilter {
    public static filter(
        mipmap: MipmapGenerator,
        targetWidth: number,
        targetHeight: number
    ): Uint8ClampedArray {
        const level1 = mipmap.findBestLevel(
            Math.max(1, targetWidth * 1.5),
            Math.max(1, targetHeight * 1.5)
        );
        const level2 = mipmap.findBestLevel(
            Math.max(1, targetWidth * 0.5),
            Math.max(1, targetHeight * 0.5)
        );
        
        const data1 = mipmap.getLevel(level1)!;
        const data2 = mipmap.getLevel(level2)!;
        
        const [w1, h1] = mipmap.getLevelSize(level1)!;
        const [w2, h2] = mipmap.getLevelSize(level2)!;
        
        const weight = (targetWidth * targetHeight) / (w1 * h1);
        
        return this.interpolate(data1, w1, h1, data2, w2, h2, weight);
    }
 
    private static interpolate(
        data1: Uint8ClampedArray,
        w1: number,
        h1: number,
        data2: Uint8ClampedArray,
        w2: number,
        h2: number,
        weight: number
    ): Uint8ClampedArray {
        const result = new Uint8ClampedArray(w1 * h1 * 4);
        
        for (let i = 0; i < result.length; i += 4) {
            const r = Math.round(
                data1[i] * weight + data2[i] * (1 - weight)
            );
            const g = Math.round(
                data1[i+1] * weight + data2[i+1] * (1 - weight)
            );
            const b = Math.round(
                data1[i+2] * weight + data2[i+2] * (1 - weight)
            );
            const a = Math.round(
                data1[i+3] * weight + data2[i+3] * (1 - weight)
            );
            
            result[i] = r;
            result[i+1] = g;
            result[i+2] = b;
            result[i+3] = a;
        }
        
        return result;
    }
}